<?php

abstract class Query
{
    abstract protected function record($data);

    public function select()
    {

    }
}

class Model extends Query
{
    // 静态实例类
    private static $instance = null;

    protected $filed = [];

    public function select()
    {
        $this->record(['name' => 'yang']);
    }

    protected function record($data)
    {
        $this->filed = $data;
    }

    public function all()
    {
        $this->select();
        return $this->filed;
    }

    public function __get($name)
    {
        echo __METHOD__;

        return array_key_exists($name, $this->filed) ? $this->filed[$name] : null;
    }

    public function __set($name, $value)
    {
        echo __METHOD__;
        $this->filed[$name] = $value;
    }

    public function __isset($name)
    {
        return isset($this->filed[$name]);
    }

    public function __unset($name)
    {
        echo __METHOD__;
        if (array_key_exists($name, $this->filed)) {
            $this->filed[$name] = null;
        }
    }

    public function __call($method, $arguments)
    {
        // echo $method;
        $prefix = substr($method, 0, 3);

        if (in_array($prefix, ['get', 'set'])) {
            switch ($prefix) {
                case 'get':
                    $property = '_' . strtolower(substr($method, 3));
                    if (property_exists($this, $property)) {
                        return $this->{$property};
                    } else {
                        return null;
                    }
                    break;
                case 'set':
                    $property = '_' . strtolower(substr($method, 3));
                    if (property_exists($this, $property)) {
                        $this->{$property} = $arguments[0];
                    } else {
                        return null;
                    }
                    break;
                default:
                    return false;
            }
        }

        $action = 'getAttribute' . ucfirst($method);
        if (method_exists($this, $action)) {
            return call_user_func_array([$this, $action], $arguments);
        }
    }

    public static function __callStatic($method, $arguments)
    {
        if (is_null(self::$instance)) {
            self::$instance = new static();
            return call_user_func_array([self::$instance, $method], $arguments);
        }

        // return call_user_func_array([new static(), $method], $arguments);

        // return call_user_func([new static(), '__call'], $method, $arguments);

        // return (new static)->$method(...$arguments);
    }


}

class User extends Model
{
    public $_name;

    protected function getAttributeMobile()
    {
        return 'mobile';
    }

    public function getAll($params)
    {
        echo $params . '天气预报';
    }
}

$obj = new User();
// print_r($obj->all());

/**
 * __get 、__set 属性重载
 */
// 给属性赋值时 会调用 __set()
// $obj->name = 1;
// $obj->b = 1;

// 获取属性值时 会调用 __get()
// echo $obj->name;
// echo $obj->test;

// 执行 unset 时 会调用 __unset()
// unset($obj->name);

// 执行 isset() 或 empty 时 会调用 __isset()
// echo isset($obj->test);

/**
 * __call、__callStatic 方法重载
 */
// $obj->setName('test1');
// echo $obj->getName();
//
// echo $obj->mobile();

print_r(User::getAll('11'));
